//Sound Daemon
//forked Sep 22, 2012
//intent: raspi music player
#include <stdlib.h>
#include <sys/types.h>
#include <dirent.h> //opendir();
#include <sys/stat.h>
#include <unistd.h>

#include <time.h>

//do my includes
#include "../include/soundplayer.h"
#include "../include/decodemodules.h"

environment_t env;
char* dname; //i need to append the filename to the open directory path

long* parse_directory(DIR* d){
	int x = 1;
	long* offset = NULL;


	struct dirent* entries;

	if (d != NULL){          //sucessfully paired with DIR*
		//do stuff with the open directory
		while (1){
			if ((entries = readdir(d)) != NULL){
				offset = realloc(offset, (sizeof(long)*(x+1)));         //add new long to array
				offset[x] = telldir(d);         //store offset
				x++;
			}
			else {
				break;
			}
		}
	}
	else {
		return NULL;
	}
	offset[0] = x; //return the number of files

	return offset;
}

int seedrand(){
	//a more robust method of handling the randomizer
	static unsigned int oldseed = 0;
	unsigned int newseed;

	newseed = time(NULL);

	if (newseed != oldseed) {
		srand(newseed);
		return 0;
	}
	else{
		srand(rand());
		return 1;
	}
}

char* get_rand_filename(DIR* d, int total_files, long* filelist){
	//select a random filename and return a pointer to it
	struct stat f;
	fstat(dirfd(d), &f);

	struct dirent* entry;
	int index = 0;
	//srand(time(NULL));
	seedrand();
	index = rand()%total_files; //this overrides the srand(rand()) rebreaking the found . and .. bug
	seekdir(d, filelist[index]);
	entry = readdir(d);
	char* filename = concat(dname, entry->d_name); //I've made sure to free this buffer
	printf("%s\n", filename);
	env->format = qualify_filename(filename);
	return filename;
}

int check_input(int fd){
	struct stat file_info;

	fstat(fd, &file_info);   //get file info
	env->size = (unsigned long) file_info.st_size;

	//conditional statements
	return S_ISREG(file_info.st_mode) ? 1 : 0;
}

int main(int argc, char** argv){
	//parse command line options
	env = new_soundplayer_environment(); //initialize the environment

	int parse;

	while (( parse = getopt(argc, argv, "o:a:")) != -1){
		switch (parse){
		case 'o':
			if (cmp("alsa", optarg) == 0){
				env->audio_out = 0;
			}
			else if (cmp("oss", optarg) == 0){
				env->audio_out = 1;
			}
			else {
				env->audio_out = -1;
				env->filename = (char *) malloc(sizeof(optarg)); //hold the string
				env->filename = optarg; //put the string there
			}
			break;
		case 'a':
			env->audio_device = optarg;
		}
	}

	//variables
	FILE* input = NULL; //file handle
	DIR* d = NULL; //dir handle
	char* filename; //this is so i don't lose allocated memory

	if ( argc > 0 ) {
		d = opendir(argv[argc-1]); //open a directory
		dname = calloc(1, 255); //big buffer
		dname = argv[argc-1]; //will this do it?
	}
	long* filelist = NULL; //do declarations outside of conditionals...standards compliance

	if ( (filelist = parse_directory(d)) == NULL ) return 1; //directory was invalid

	int total_files = filelist[0];

	if (pcm_output_init() == 0){
		while (1){
			filename = get_rand_filename(d, total_files, filelist);
			input = fopen(filename, "r");
			if (check_input(fileno(input)) != 0){
				switch (env->format){
				case TYPE_WAVE:
					play_wav(input);
					break;
				case TYPE_MP3:
					play_mp3(input);
					break;
				case TYPE_OGG:
					play_ogg(input);
					break;
				case TYPE_AAC:
					play_aac(input);
					break;
				case TYPE_FLAC:
					play_flac(input);
					break;
				default:
					printf("Invalid or no codec selected\n");
				}
			}
			else {
				srand(rand());
			}
			fclose(input);
			free(filename); //be nice
		}
	}

	pcm_output_term(); //destroy sound
	closedir(d);

	return 0;
}
